package com.winit.operation;

import com.winit.beetleAuth.model.User;
import com.winit.beetleAuth.repository.RoleRepository;
import com.winit.beetleAuth.repository.UserRepository;
import com.winit.beetleAuth.repository.UserRepositoryExt;
import com.winit.common.Md5Util;
import com.winit.commons.util.SeqGenerate;
import com.winit.employeInfo.model.Dept;
import com.winit.employeInfo.model.Employee;
import com.winit.employeeDataExtract.EmployeeDataExtractor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class BeetleOathUpdator {

    private static Logger log = LoggerFactory.getLogger(BeetleOathUpdator.class);
    private static final String DEFAULT_PASSWORD = "888888";

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private UserRepositoryExt userRepositoryExt;

    private List<String> yfdept = new ArrayList<>();
    private List<String> devdept = new ArrayList<>();
    private List<String> qadept = new ArrayList<>();
    private List<String> opsdept = new ArrayList<>();
    private List<String> pdmdept = new ArrayList<>();

    public boolean execute() {
        log.info("syn user between hr and beetle auth,start..");
        getDept();
        List<Employee> employees = null;
        try {
            employees = EmployeeDataExtractor.extractEmployee();
        } catch (Exception e) {
            log.error(e.getMessage() + "now operation extractEmployee will try again", e);
            try {
                employees = EmployeeDataExtractor.extractEmployee();
            } catch (Exception e1) {
                log.error("operation extractEmployee failed again, job aborted..");
                log.error(e.getMessage(), e);
                return false;
            }
        }

//        String roleId = this.roleRepository.findByRoleName("matrix").getRoleId();
//        String pdRoleId = this.roleRepository.findByRoleName("pd").getRoleId();
        String devRoleId = this.roleRepository.findByRoleName("dev").getRoleId();
        String qaRoleId = this.roleRepository.findByRoleName("qa").getRoleId();
        String opsRoleId = this.roleRepository.findByRoleName("ops").getRoleId();
        String pdmRoleId = this.roleRepository.findByRoleName("pdm").getRoleId();
        String ptRoleId = this.roleRepository.findByRoleName("pt").getRoleId();
        String yfRoleId = this.roleRepository.findByRoleName("yf").getRoleId();

        int i = 0;
        for (Employee employee : employees) {
            String role = getUserRole(devRoleId, qaRoleId, opsRoleId, pdmRoleId, employee);

            String email = employee.getEmail();
            if ("1".equalsIgnoreCase(employee.getHirestate()) && (!StringUtils.isEmpty(email))) {
                List<User> exists = this.userRepository.findByAccount(email.substring(0, email.indexOf("@")));
                if (!CollectionUtils.isEmpty(exists)) {  //如果存在
                    if (!StringUtils.isEmpty(role)) {
                        this.updateUserInfo(exists.get(0), employee, new String[]{role, yfRoleId});
                    } else {
                        this.updateUserInfo(exists.get(0), employee, new String[]{ptRoleId});
                    }
                    continue;
                }
                String roleIds = "|";
                if (!StringUtils.isEmpty(role)) {
                    roleIds = roleIds + role + "|" + yfRoleId + "|";
                } else {
                    roleIds = roleIds + ptRoleId + "|";
                }
                this.createUser(employee, roleIds);
                i++;
            }

        }
        log.info(i + " items of user added...");
        log.info("syn user between hr and beetle auth,end..");
        return true;
    }

    private void getDept() {
        yfdept = new ArrayList<>();
        devdept = new ArrayList<>();
        qadept = new ArrayList<>();
        opsdept = new ArrayList<>();
        pdmdept = new ArrayList<>();
        try {
            List<Dept> depts = EmployeeDataExtractor.extractDept();
            for (Dept dept : depts) {
                if ("Y".equals(dept.getIsdisable())) {
                    continue;
                }
                //研发中心部门
                if ("YF01".equals(dept.getDeptcode()) || "YF01".equals(dept.getSupername()) || yfdept.contains(dept.getSupername())) {
                    yfdept.add(dept.getDeptcode());
                    if (dept.getDeptname().contains("技术产品管理部") || pdmdept.contains(dept.getSupername())
                            || dept.getDeptname().contains("产品")) {
                        pdmdept.add(dept.getDeptcode());
                    } else if (dept.getDeptname().contains("质量保证部") || qadept.contains(dept.getSupername())
                            || dept.getDeptname().contains("测试")) {
                        qadept.add(dept.getDeptcode());
                    } else if (dept.getDeptname().contains("运维支持部") || opsdept.contains(dept.getSupername())) {
                        opsdept.add(dept.getDeptcode());
                    } else {
                        devdept.add(dept.getDeptcode());
                    }
                }
            }
        } catch (Exception e) {
            log.error("com.winit.operation.BeetleOathUpdator.getDept", e);
        }
    }

    private String getUserRole(String devRoleId, String qaRoleId, String opsRoleId, String pdmRoleId, Employee employee) {
        if (!yfdept.contains(employee.getDeptcode())) {
            return null;
        }
        if (devdept.contains(employee.getDeptcode())) {
            return devRoleId;
        }
        if (qadept.contains(employee.getDeptcode())) {
            return qaRoleId;
        }
        if (opsdept.contains(employee.getDeptcode())) {
            return opsRoleId;
        }
        if (pdmdept.contains(employee.getDeptcode())) {
            return pdmRoleId;
        }
        return null;
    }

    @Transactional
    public void updateUserInfo(User entity, Employee employee, String[] roleIds) {
//        User entity = this.userRepositoryExt.find(User.class, user.getId());
        boolean shouldUpdate = false;
        if (StringUtils.isEmpty(entity.getEmail())) {
            entity.setEmail(employee.getEmail());
            shouldUpdate = true;
        }
        if (StringUtils.isEmpty(entity.getEmpno())) {
            entity.setEmpno(employee.getEmpno());
            shouldUpdate = true;
        }
        if (StringUtils.isEmpty(entity.getMobile())) {
            entity.setMobile(employee.getMobilenumber());
            shouldUpdate = true;
        }
        if (StringUtils.isEmpty(entity.getRealname())) {
            entity.setRealname(employee.getEmpname());
            shouldUpdate = true;
        }
        if (StringUtils.isEmpty(entity.getRole())) {
            String role = "|";
            for (String roleId : roleIds) {
                role = role + roleId + "|";
            }
            entity.setRole(role);
            shouldUpdate = true;
        } else {
            String existRole = entity.getRole();
            String[] existRoleIds = existRole.split("\\|");
            List<String> existsRoleIdsLst = Arrays.asList(existRoleIds);
            for (String roleId : roleIds) {
                if (!existsRoleIdsLst.contains(roleId)) {
                    shouldUpdate = true;
                    existRole = existRole.endsWith("|") ? existRole + roleId + "|" : existRole + "|" + roleId + "|";
                }
            }
            if (entity.getRole().length() != existRole.length()) {
                entity.setRole(existRole);
            }
        }
        if (shouldUpdate) {
            this.userRepositoryExt.updateUser(entity);
//            entityManager.merge(entity);
//            entityManager.flush();
        }
    }

    private void createUser(Employee employee, String roleIds) {
        User user = this.getUserFromEmployee(employee, roleIds);
        this.userRepository.save(user);
    }


    private User getUserFromEmployee(Employee employee, String roleIds) {
        User user = new User();
        user.setId(SeqGenerate.createId("U"));
        user.setPassword(Md5Util.parseStrToMd5L32(DEFAULT_PASSWORD));
        String email = employee.getEmail();
        user.setEmail(email);
        user.setAccount(email.substring(0, email.indexOf("@")));
        user.setRealname(employee.getEmpname());
        user.setRole(roleIds);
        user.setEmpno(employee.getEmpno());
        user.setMobile(employee.getMobilenumber());
        return user;
    }

}
